package com.ruoyi.common.core.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.ruoyi.common.core.annotation.jackson.JsonFormatCustomer;
import com.ruoyi.common.core.utils.CommonUtils;
import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * <p>
 * 作用：LocalDateTime格式化
 * </p>
 *
 * @author zhanglianbao
 * @since 2025-02-08 12:39
 */
public class LocalTimeSerializer extends StdSerializer<LocalTime> implements
    ContextualSerializer {

  final ConcurrentMap<String, LocalTimeSerializer> serializers = new ConcurrentHashMap<>();
  private DateTimeFormatter formatter;

  // 默认构造函数
  public LocalTimeSerializer() {
    this(DateTimeFormatter.ofPattern("HH:mm:ss"));
  }

  // 带格式的构造函数
  public LocalTimeSerializer(DateTimeFormatter formatter) {
    super(LocalTime.class);
    this.formatter = formatter;
  }

  @Override
  public void serialize(LocalTime value, JsonGenerator gen, SerializerProvider provider)
      throws IOException {
    gen.writeString(formatter.format(value));
  }

  @Override
  public JsonSerializer<?> createContextual(SerializerProvider prov,
      BeanProperty property) {
    // 如果有自定义的格式化注解，返回一个新的序列化器实例
    JsonFormatCustomer formatCustomer = property.getAnnotation(JsonFormatCustomer.class);
    if (formatCustomer != null && CommonUtils.hasText(formatCustomer.pattern())) {
      if (serializers.containsKey(formatCustomer.pattern())) {
        return serializers.get(formatCustomer.pattern());
      } else {
        final LocalTimeSerializer serializer = new LocalTimeSerializer(
            DateTimeFormatter.ofPattern(formatCustomer.pattern()));
        serializers.putIfAbsent(formatCustomer.pattern(), serializer);
        return serializer;
      }
    }
    return this;
  }
}
